﻿# CoffeeScript
if not window.Moshu
    window.Moshu = new Object()
window.Moshu.Canvas2D.Components = new Object()

# data structure to keep a list of sprite indexes, and the interval of changing them
class Moshu.Canvas2D.Components.AnimationStep extends Moshu.Observable
    constructor : ()->
        @flip = false
        @steps = []
        @continous = true
        @index = 0
        @interval = 200
        @lastTime = 0
        @finished = false
        @continueFrom = 0
    getCurrent : ()->        
        @steps[@index]
    finish : ()->
        @finished = true        
        @notify("animation-finished",null);
    update : (dt)->        
        if not @finished
            if @steps.length>1
                @lastTime+=dt
                if @lastTime > @interval
                    # reset last time
                    #debugger;
                    @lastTime = @lastTime % @interval            
                    #compute new index
                    if @index>=@steps.length-1
                        if @continous
                            @index = @continueFrom
                        else
                            finish()
                    else
                        @index++
            else @index = 0
                
# Hero, jumping and moving hero    
class Moshu.Canvas2D.Components.Hero
    constructor : (@world, @position, @height)->
        @statuses = [
            RESTING = "resting",
            MOVING = "moving",
            JUMPING = "jumping",
            CHANGING_DIRECTION = "changing-direction"
        ]
        @status = @statuses.RESTING
        @direction = 0
        # hero speed on ox axis
        @speed = 150
        
        # create the hero image
        @image = new Moshu.Canvas2D.CanvasImage("./images/sprites/prince.png", @position.x(), @position.y(), 0, @height)        
        @image.velocity(new Moshu.Canvas2D.Vector(@speed,0))   
        # register sprites
        # resting sprites        
        @image.registerSprite("stopped", 336, 15, 36, 84)
        
        # running sprites                        
        @image.registerSprite("run1",32,138,44,84)        
        @image.registerSprite("run2",81,138,44,84)
        @image.registerSprite("run3",134,138,44,84)
        @image.registerSprite("run4",184,138,54,84)
        @image.registerSprite("run5",235,138,54,84)
        @image.registerSprite("run6",293,138,54,84)
        
        @image.registerSprite("run7",353,138,65,84)
        @image.registerSprite("run8",419,138,65,84)
        @image.registerSprite("run9",488,138,50,84)
        @image.registerSprite("run10",540,138,50,84)
        
        @image.registerSprite("run11",600,138,65,84)
        @image.registerSprite("run12",674,138,60,84)
        @image.registerSprite("run13", 734, 138, 45, 84)
        
        
        #create painter and add hero        
        @imagePainter = new Moshu.Canvas2D.ImagePainter(@world.context, @image)
        @world.createShape(@image, @imagePainter)
        #initialize with stopped position
        @stop()
        
        # register to the animation step event
        window.Moshu.AnimationManager.bind(this, @timeUpdate)        
                
    #stop the hero     
    stop : ()->
        @animation = new Moshu.Canvas2D.Components.AnimationStep()
        @animation.flip = false
        @animation.steps = [0]
        @animation.continous = false        
        @direction = 1
        @status = @statuses.RESTING
    #start the hero moving
    startMoving:()->              
        if @direction is 1
            @animation = new Moshu.Canvas2D.Components.AnimationStep()
            @animation.flip = true
            @animation.steps = [1,2,3,4,5,6,7,8,9,10,11,12,13]
            @animation.continueFrom = 6
            
            # set sprite speed in inverse to the hero speed
            # consider 300 as max speed , we might want to configure this better after tests
            @animation.interval = 300 - @speed
            # make sure we do not set it under 50 milliseconds
            if @animation.interval < 50
                @animation.interval = 50            
            @status = @statuses.MOVING
            
    #jump the hero
    jump : ()->
        @status = @statuses.JUMPING
    #change hero's directio on horizontal axis
    changeDirection:()->
        @status = @statuses.CHANGING_DIRECTION        
    # event handler for animation step, compute the hero image and set it as sprite
    timeUpdate : (dt) ->
        if @animation
            @animation.update(dt)
            spriteIndex = @animation.getCurrent()
            @image.selectSpriteByIndex(spriteIndex)
    
        
    